package com.mach.platform.aop;


import com.google.common.base.Splitter;
import com.mach.platform.domain.Response;
import com.mach.platform.domain.iot.IotDev;
import com.mach.platform.utils.CacheUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Slf4j
@Aspect
@Component
public class DevCacheAspect {

    String CACHE_NAME_PREFIX = "DEVCACHE_";


    @Pointcut(value = "@annotation(com.mach.platform.innotation.DevCache)")
    public void annotation() {
    }

    @Around("annotation()")
    public Object checkCache(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        Long argId = Long.parseLong(args[0].toString());

        Object result = null;
        if (args.length > 0) {
            Object existCache = CacheUtils.guavaCacheFactory.getIfPresent(CACHE_NAME_PREFIX + argId);
            if (existCache == null) {
                result = joinPoint.proceed();
                CacheUtils.guavaCacheFactory.put(CACHE_NAME_PREFIX + argId, result);
            } else {
                result = existCache;
            }
        }
        return result;
    }

    @Around(value = "@annotation(com.mach.platform.innotation.DevToCache)")
    public Object insertCache(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = null;
        result = joinPoint.proceed();
        IotDev dev = (IotDev) result;
        CacheUtils.guavaCacheFactory.put(CACHE_NAME_PREFIX + dev.getId(), result);
        return result;
    }

    /**
     * 清除所有缓存
     * @param joinPoint
     * @throws Throwable
     */
    @Around(value = "@annotation(com.mach.platform.innotation.DelCache)")
    public void delCache(ProceedingJoinPoint joinPoint) throws Throwable {
        joinPoint.proceed();
        CacheUtils.guavaCacheFactory.invalidateAll();
    }

    /**
     * EMS缓存
     * @param joinPoint
     * @throws Throwable
     */
    @Around(value = "@annotation(com.mach.platform.innotation.EMSCache)")
    public Response emsCache(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();

        HashMap<String, Object> param = (HashMap<String, Object>) args[1];

        if (param.size() <= 1){
            return (Response) joinPoint.proceed();
        }
        if (param.get("time") == null) {
            return (Response) joinPoint.proceed();
        }
        String time = param.get("time").toString();



        String name = param.get("name").toString();
        String workSpaceName = param.get("workSpaceName").toString();
        String id = param.get("id").toString();
        Object objSelectType = param.get("selectType");
        String selectType = "";
        if (!Objects.isNull(objSelectType)){
            selectType = objSelectType.toString();
        }

        String KEY_CACHE = time + name + workSpaceName + id + selectType;

        Response resultCache;
        if (judgeTime(time)){//当前年、当前月、当前天不进缓存
            resultCache = (Response) joinPoint.proceed();
        } else{
            resultCache = (Response) CacheUtils.guavaCacheFactoryEMS.getIfPresent(KEY_CACHE);
            if (Objects.isNull(resultCache) || Objects.isNull(resultCache.getJsData())){
                resultCache = (Response) joinPoint.proceed();
                CacheUtils.guavaCacheFactoryEMS.put(KEY_CACHE, resultCache);
            }
        }


        return resultCache;
    }

    /**
     * 判断时间是否是当前年、当前月、当前天
     * @param time
     * @return
     */
    private static boolean judgeTime(String time) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate today = LocalDate.now();
        if (time.length() == 4) { // 年
            return Integer.parseInt(time) == today.getYear();
        } else if (time.length() == 7) { // 月
            String todayStr = today.format(fmt);
            boolean result = Objects.equals(todayStr.substring(0, 7), time);
            return result;
        } else if (time.length() == 10) { // 天
            String todayStr = today.format(fmt);
            boolean result = Objects.equals(todayStr, time);
            return result;
        }
        return false;
    }

//    public static void main(String[] args) {
//        System.out.println(judgeTime("2019-10-"));
//    }


}
